home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ABUSESRC.ZIP / AbuseSrc / imlib / port / dos4gw / sound.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-30  |  13.4 KB  |  583 lines

  1. extern "C" {
  2. #include "sos.h"
  3. #include "sosm.h"
  4. } ;
  5.  
  6. #include "profile.h"
  7. #include "readwav.hpp"
  8. #include "jmalloc.hpp"
  9. #include <stdlib.h>
  10. #include "sound.hpp"
  11. #include <stdio.h>
  12. #include "dprint.hpp"
  13. #include "specs.hpp"
  14. #include "doscall.hpp"
  15. #include "specs.hpp"
  16. #include "macs.hpp"
  17. #include "timing.hpp"
  18. #include <dos.h>
  19.  
  20. static W32      wDIGIDeviceID=-1;                            // digital device ID
  21. static W32      wMIDIDeviceID=-1;                            // midi device ID
  22.  
  23. static uchar sos_need_uninit_midi_system=0,
  24.              sos_need_uninit_midi_driver=0,
  25.              sos_need_uninit_digi_system=0,
  26.              sos_need_uninit_digi_driver=0,
  27.          sos_need_uninit_timer=0,
  28.              sos_need_remove_timer_event=0;
  29.  
  30. static HANDLE             hDIGIDriver;               // handle to digital driver
  31. static HANDLE             hMIDIDriver;               // handle to MIDI driver
  32. static HANDLE             hDIGITimer;                // handle to digital mixer
  33. static _SOS_DIGI_DRIVER   sDIGIDriver;               // digital driver structure
  34. static _SOS_MIDI_DRIVER   sMIDIDriver;               // midi driver structure
  35. static PSTR               pMelodicPatch=NULL;        // melodic FM instruments
  36. static PSTR               pDrumPatch=NULL;           // drum FM instruments
  37. static _SOS_SAMPLE        sos_sam;
  38. static int s_init=0;                   // flags saying what has been initalized
  39.  
  40. extern void add_timer_call(void ( *fun)(), int and_call_mask);
  41. extern void remove_timer_call(void ( *fun)());
  42.  
  43. void print_sound_options() { ; }                         // print the options avaible for sound
  44. void song::set_volume(int volume)  // 0..127
  45.   if ((s_init&MUSIC_INITIALIZED) && data)
  46.     sosMIDISetSongVolume(song_id,volume);
  47. }
  48.  
  49. extern void (*install_timer_handler)(void (*fun)())=NULL;   // function to install timer
  50. extern void (*uninstall_timer_handler)()=NULL;
  51.  
  52. static HANDLE jc_timer_handle;
  53. extern uchar timer_installed;
  54. static void install_timer(void (*fun)())
  55. {
  56.   sosTIMERRegisterEvent(100,fun,&jc_timer_handle);
  57. }
  58.  
  59. static void uninstall_timer()
  60. {
  61.   sosTIMERRemoveEvent( jc_timer_handle);
  62. }
  63. // BOOL  sosEZGetConfig( PSTR szName )
  64. BOOL sosEZGetConfig(char *szName )
  65. {
  66.  _INI_INSTANCE  sInstance;
  67.  BOOL           wError;
  68.  
  69.  // reset digital and MIDI driver structures
  70.  memset( &sDIGIDriver, 0, sizeof( _SOS_DIGI_DRIVER ) );
  71.  memset( &sMIDIDriver, 0, sizeof( _SOS_MIDI_DRIVER ));
  72.  
  73.  // open .ini file 
  74.  if ( !hmiINIOpen( &sInstance, szName ) )
  75.  return( _FALSE );
  76.  
  77.  // locate section for digital settings
  78.  if ( !hmiINILocateSection( &sInstance, "DIGITAL" ) )
  79.  {  
  80.     // close file
  81.     hmiINIClose( &sInstance );
  82.     
  83.     // return error
  84.     return( _FALSE );
  85.   }
  86.  
  87.  // fetch device ID, Port, DMA, IRQ
  88.  wError   =  hmiINIGetItemDecimal( &sInstance, "DeviceID", &wDIGIDeviceID );
  89.  wError   =  hmiINIGetItemDecimal( &sInstance, "DevicePort", &sDIGIDriver.sHardware.wPort );
  90.  wError   =  hmiINIGetItemDecimal( &sInstance, "DeviceDMA", &sDIGIDriver.sHardware.wDMA );
  91.  wError   =  hmiINIGetItemDecimal( &sInstance, "DeviceIRQ", &sDIGIDriver.sHardware.wIRQ );
  92.  
  93.  // error
  94.  if ( !wError )
  95.  {
  96.   // close file
  97.   hmiINIClose( &sInstance );
  98.   
  99.   // return error
  100.   return( _FALSE );
  101. }
  102.  
  103.  // locate section for MIDI settings
  104.  if ( !hmiINILocateSection( &sInstance, "MIDI" ) )
  105.  {  
  106.     // close file
  107.     hmiINIClose( &sInstance );
  108.     
  109.     // return error
  110.     return( _FALSE );
  111.   }
  112.  
  113.  // fetch device ID, Port, DMA, IRQ
  114.  wError   =  hmiINIGetItemDecimal( &sInstance, "DeviceID", &wMIDIDeviceID );
  115.  wError   =  hmiINIGetItemDecimal( &sInstance, "DevicePort", &sMIDIDriver.sHardware.wPort );
  116.  
  117.  // error
  118.  if ( !wError )
  119.  {
  120.   // close file
  121.   hmiINIClose( &sInstance );
  122.   
  123.   // return error
  124.   return( _FALSE );
  125. }
  126.  
  127.  // close file
  128.  hmiINIClose( &sInstance );
  129.  
  130.  // return success
  131.  return( _TRUE );
  132. }
  133.  
  134. int sosEZInitSystem2(W32 wDDeviceID, W32 wMDeviceID )
  135. {
  136.   // set up the digital driver
  137.   sDIGIDriver.wDriverRate       =  11025;
  138.   sDIGIDriver.wDMABufferSize    =  0x1000;
  139.  
  140.   int inst=timer_installed;
  141.   if (inst)    // if a timer is already installed, uninstall and reinstall with us    
  142.     timer_uninit();
  143.  
  144.   install_timer_handler=install_timer;
  145.   uninstall_timer_handler=uninstall_timer;
  146.   
  147.  
  148.   // initialize the timer system
  149.   sosTIMERInitSystem( _TIMER_DOS_RATE, _SOS_DEBUG_NORMAL );
  150.   sos_need_uninit_timer=1;
  151.  
  152.   if (inst)
  153.     timer_init();
  154.  
  155.  
  156.   // initialize the digital and midi systems
  157.   sosDIGIInitSystem( _NULL, _SOS_DEBUG_NORMAL );
  158.   sos_need_uninit_digi_system=1;
  159.  
  160.   sosMIDIInitSystem( _NULL, _SOS_DEBUG_NORMAL );
  161.   sos_need_uninit_midi_system=1;
  162.  
  163.   // check to see if the midi device is to be initialized
  164.   if ( wMDeviceID != -1 )
  165.   {
  166.     // initialize MIDI
  167.     sMIDIDriver.wID = wMDeviceID;
  168.     if ( sosMIDIInitDriver( &sMIDIDriver, &hMIDIDriver ) )
  169.     {
  170.       sound_uninit();
  171.       return 0;
  172.     } else sos_need_uninit_midi_driver=1;
  173.   }
  174.  
  175.   // initialize the digital driver
  176.   if ( wDDeviceID != -1 )
  177.   {
  178.     // initialize digital
  179.     sDIGIDriver.wID = wDDeviceID;
  180.     if ( sosDIGIInitDriver( &sDIGIDriver, &hDIGIDriver ) )
  181.     {
  182.       sound_uninit();
  183.       return 0;
  184.     } else
  185.     {
  186.       sos_need_uninit_digi_driver=1;
  187.       s_init|=SFX_INITIALIZED;
  188.     }
  189.   }
  190.  
  191.  
  192.   // register digital timer event (mixer)
  193.   if ( wDDeviceID != -1  || wMDeviceID!=-1)
  194.   {
  195.     sos_need_remove_timer_event=1;
  196.  
  197.     sosTIMERRegisterEvent(100, sDIGIDriver.pfnMixFunction,
  198.             &hDIGITimer );
  199.   }
  200.  
  201.  
  202.   // check driver type, if it is an OPL2/3 driver, we
  203.   // need to load the patch files for the driver.
  204.   if (wMIDIDeviceID == _MIDI_FM || wMIDIDeviceID == _MIDI_OPL3 && wMIDIDeviceID != -1 )
  205.   {
  206.     bFILE *fp=open_file("music/melodic.bnk","rb");
  207.     if (fp->open_failure())
  208.     {
  209.       dprintf("Missing file music/melodic.bnk, sound disabled\n");
  210.       sound_uninit();
  211.       delete fp;
  212.       return 0;
  213.     }
  214.     
  215.     long l=fp->file_size();
  216.     pMelodicPatch=(PSTR)jmalloc(l,"Melodic bank");
  217.     fp->read(pMelodicPatch,l);
  218.     delete fp;
  219.  
  220.  
  221.     fp=open_file("music/drum.bnk","rb");
  222.     if (fp->open_failure())
  223.     {
  224.       dprintf("Missing file music/drum.bnk, sound disabled\n");
  225.       sound_uninit();
  226.       delete fp;
  227.       return 0;
  228.     }
  229.     
  230.     l=fp->file_size();
  231.     pDrumPatch=(PSTR)jmalloc(l,"Drum bank");
  232.     fp->read(pDrumPatch,l);
  233.     delete fp;
  234.  
  235.  
  236.     if ((sosMIDISetInsData( hMIDIDriver, (LPSTR)pMelodicPatch, 1)) || 
  237.     (sosMIDISetInsData( hMIDIDriver, (LPSTR)pDrumPatch, 1)))
  238.     {
  239.       sound_uninit();
  240.       return 0;
  241.     }
  242.     s_init|=MUSIC_INITIALIZED;
  243.   } else if (wMIDIDeviceID!=-1) 
  244.      s_init|=MUSIC_INITIALIZED;
  245.  
  246.  
  247.   return s_init;
  248. }
  249.  
  250.  
  251. void sound_uninit()
  252. {
  253.   if (sos_need_remove_timer_event)
  254.   {
  255.     sos_need_remove_timer_event=0;
  256.     sosTIMERRemoveEvent( hDIGITimer );
  257.   }
  258.  
  259.   if (sos_need_uninit_timer)
  260.   {
  261.     int inst=timer_installed;
  262.     if (inst)    // if a timer is already installed, uninstall and reinstall with us 
  263.     {
  264.       timer_uninit();
  265.       install_timer_handler=NULL;
  266.       uninstall_timer_handler=NULL;
  267.     }
  268.  
  269.  
  270.     sos_need_uninit_timer=0;
  271.     sosTIMERUnInitSystem(0);
  272.  
  273.  
  274.     if (inst)
  275.     {
  276.       timer_init();        // reinitial timer to use old method
  277.     }
  278.   }
  279.  
  280.   if (sos_need_uninit_digi_driver)
  281.   {
  282.     sos_need_uninit_digi_driver=0;
  283.     sosDIGIUnInitDriver( hDIGIDriver, _TRUE, _TRUE );
  284.     s_init&=~SFX_INITIALIZED;
  285.   }
  286.  
  287.   if (sos_need_uninit_digi_system)
  288.   {
  289.     sos_need_uninit_digi_system=0;
  290.     sosDIGIUnInitSystem();
  291.   }
  292.  
  293.  
  294.   if (sos_need_uninit_midi_driver)
  295.   {
  296.     sos_need_uninit_midi_driver=0;
  297.     sosMIDIUnInitDriver( hMIDIDriver, _TRUE );
  298.     s_init=s_init&(~MUSIC_INITIALIZED);
  299.   }
  300.  
  301.   if (sos_need_uninit_midi_system)
  302.   {
  303.     sos_need_uninit_midi_system=0;
  304.     sosMIDIUnInitSystem();
  305.   }
  306.  
  307.  
  308.  
  309.   if (pDrumPatch)
  310.   {
  311.     jfree(pDrumPatch);
  312.     pDrumPatch=NULL;
  313.   }
  314.  
  315.   if (pMelodicPatch)
  316.   {
  317.     jfree(pMelodicPatch);
  318.     pMelodicPatch=NULL;
  319.   }
  320.  
  321. }
  322.  
  323. int sound_init(int argc, char **argv)
  324. {
  325.   if (s_init!=0) sound_uninit();
  326.  
  327.   atexit(sound_uninit);
  328.   for (int i=1;i<argc;i++)
  329.   {
  330.     if (!strcmp(argv[i],"-nosound"))
  331.     {
  332.       dprintf("sound : sound disabled (-nosound)\n");
  333.       wDIGIDeviceID=-1;
  334.       wMIDIDeviceID=-1;    
  335.       return 0;
  336.     }
  337.   }
  338.  
  339.   if (sosEZGetConfig("sndcard.cfg")==_FALSE)
  340.   {
  341.     wDIGIDeviceID=-1;
  342.     wMIDIDeviceID=-1;    
  343.     dprintf("Sound configuration was not saved by setup program, sound disabled\n");
  344.     return 0;    
  345.   }
  346.  
  347.   if (wDIGIDeviceID==-1 && wMIDIDeviceID==-1)
  348.     return 0;
  349.  
  350.   memset(&sos_sam,0,sizeof(sos_sam));
  351.   sos_sam.wBitsPerSample=8;
  352.   sos_sam.wChannels=1;
  353.   sos_sam.wFormat=_PCM_UNSIGNED;
  354.   sos_sam.wRate=11025;
  355.   sos_sam.wPanPosition=_PAN_CENTER;
  356.  
  357.  
  358.   return sosEZInitSystem2(wDIGIDeviceID, wMIDIDeviceID);
  359.  
  360.  
  361.  
  362. /*  sosTIMERInitSystem( _TIMER_DOS_RATE, _SOS_DEBUG_NORMAL );    
  363.   sos_need_uninit_timer=1;
  364.   sosDIGIInitSystem( _NULL, _SOS_DEBUG_NORMAL );
  365.   sos_need_uninit_digi=1;
  366.   sosMIDIInitSystem(_NULL,_SOS_DEBUG_NORMAL);
  367.   sos_need_uninit_midi=1;
  368.  
  369.  
  370.   if (wDIGIDeviceID!=-1)
  371.   {
  372.     sDIGIDriver.wDriverRate       =  11025;
  373.     sDIGIDriver.wDMABufferSize    =  0x1000;
  374.  
  375.     sDIGIDriver.wID = wDIGIDeviceID;
  376.  
  377.     if ( sosDIGIInitDriver( &sDIGIDriver, &hDIGIDriver ) )
  378.     {
  379.       sound_uninit();
  380.       return 0;
  381.     }
  382.     int inst=timer_installed;
  383.     if (inst)    // if a timer is already installed, uninstall and reinstall with us    
  384.       timer_uninit();
  385.  
  386.     install_timer_handler=install_timer;
  387.     uninstall_timer_handler=uninstall_timer;
  388.   
  389.     if (inst)
  390.       timer_init();
  391.  
  392.     sosTIMERRegisterEvent(100,sDIGIDriver.pfnMixFunction,
  393.               &hDIGITimer );
  394.     sos_need_remove_timer_event=1;
  395.  
  396.     s_init|=SFX_INITIALIZED;
  397.   }
  398.  
  399.   if (wMIDIDeviceID!=-1)
  400.   {
  401.     sMIDIDriver.wID = wMIDIDeviceID;
  402.     if (sosMIDIInitDriver( &sMIDIDriver, &hMIDIDriver ))
  403.     {
  404.       sound_uninit();
  405.       return 0;
  406.     }
  407.   } 
  408.  
  409.  
  410.  
  411.  
  412.  
  413.  
  414.  
  415.   // check driver type, if it is an OPL2/3 driver, we
  416.   // need to load the patch files for the driver.
  417.   if (wMIDIDeviceID == _MIDI_FM || wMIDIDeviceID == _MIDI_OPL3 && wMIDIDeviceID != -1 )
  418.   {
  419.     bFILE *fp=open_file("music/melodic.bnk","rb");
  420.     if (fp->open_failure())
  421.     {
  422.       dprintf("Missing file music/melodic.bnk, sound disabled\n");
  423.       sound_uninit();
  424.       delete fp;
  425.       return 0;
  426.     }
  427.     
  428.     long l=fp->file_size();
  429.     pMelodicPatch=(PSTR)jmalloc(l,"Melodic bank");
  430.     fp->read(pMelodicPatch,l);
  431.     delete fp;
  432.  
  433.  
  434.     fp=open_file("music/drum.bnk","rb");
  435.     if (fp->open_failure())
  436.     {
  437.       dprintf("Missing file music/drum.bnk, sound disabled\n");
  438.       sound_uninit();
  439.       delete fp;
  440.       return 0;
  441.     }
  442.     
  443.     l=fp->file_size();
  444.     pDrumPatch=(PSTR)jmalloc(l,"Drum bank");
  445.     fp->read(pDrumPatch,l);
  446.     delete fp;
  447.  
  448.  
  449.     if ((sosMIDISetInsData( hMIDIDriver, (LPSTR)pMelodicPatch, 1)) || 
  450.     (sosMIDISetInsData( hMIDIDriver, (LPSTR)pDrumPatch, 1)))
  451.     {
  452.       sound_uninit();
  453.       return 0;
  454.     }
  455.     s_init|=MUSIC_INITIALIZED;
  456.   } else if (wMIDIDeviceID!=-1) s_init|=MUSIC_INITIALIZED;
  457.  
  458.   memset(&sos_sam,0,sizeof(sos_sam));
  459.   sos_sam.wBitsPerSample=8;
  460.   sos_sam.wChannels=1;
  461.   sos_sam.wFormat=_PCM_UNSIGNED;
  462.   sos_sam.wRate=11025;
  463.   sos_sam.wPanPosition=_PAN_CENTER;
  464.  
  465.   return s_init; */
  466. }
  467.  
  468. sound_effect::sound_effect(char *filename)
  469. {  
  470.   if (s_init&SFX_INITIALIZED)
  471.   {
  472.     long sample_speed;
  473.     data=(void *)read_wav(filename,sample_speed,size);  
  474.   } else data=NULL;
  475. };
  476.  
  477.  
  478.  
  479.  
  480. void sound_effect::play(int volume, int pitch, int panpot)
  481. {
  482.   if ((s_init&SFX_INITIALIZED) && data)
  483.   {
  484.     sos_sam.pSample=(PSTR)data;
  485.     sos_sam.wLength=size;
  486.     sos_sam.wVolume=MK_VOLUME( ((volume<<8)|0xff) , ((volume<<8)|0xff));
  487.     sosDIGIStartSample( hDIGIDriver, &sos_sam);
  488.   }
  489. }
  490.  
  491.  
  492. sound_effect::~sound_effect() 
  493.   if (data)
  494.     jfree(data);       // hope it's not still playing!!! :)
  495. }
  496.  
  497. song::song(char *filename) 
  498. {
  499.   data=NULL;
  500.   if (s_init&MUSIC_INITIALIZED)
  501.   {
  502.     bFILE *fp=open_file(filename,"rb");
  503.     if (!fp->open_failure())
  504.     {
  505.       long l=fp->file_size();
  506.       data=(uchar *)jmalloc(l+sizeof(_SOS_MIDI_SONG),"song");
  507.  
  508.       _SOS_MIDI_SONG *sSong;
  509.       sSong= (_SOS_MIDI_SONG *)data;
  510.       memset( sSong, 0, sizeof( _SOS_MIDI_SONG ) );
  511.       sSong->pSong =  ( PSTR )( data + sizeof( _SOS_MIDI_SONG ));
  512.  
  513.       fp->read(sSong->pSong,l);
  514.       W32 hSong;
  515.       int err;
  516.  
  517.  
  518.       if (err=sosMIDIInitSong( sSong, &hSong ))
  519.       {
  520.     dprintf("Error while registering song %s\n",filename);
  521.     if (err==_ERR_NO_HANDLES)
  522.     dprintf("out of handles\n");
  523.     else if (err==_ERR_INVALID_DATA)
  524.     dprintf("invaild data in file\n");
  525.  
  526.     jfree(data);
  527.     data=NULL;      
  528.       } else song_id=hSong;      
  529.     }
  530.     delete fp;
  531.   }
  532. }
  533.  
  534. void song::play(unsigned char volume) 
  535. {
  536.   if (s_init&MUSIC_INITIALIZED)
  537.   {
  538.     if (data)
  539.     {
  540.       sosMIDIStartSong((W32)song_id);
  541.       set_volume(volume);
  542.     }
  543.   }
  544. }
  545.  
  546.  
  547. void song::stop(long fadeout_time) 
  548.   if ((s_init&MUSIC_INITIALIZED) && data)
  549.     sosMIDIStopSong((W32)song_id);
  550. }                                        // time in ms
  551.  
  552.  
  553. int song::playing() 
  554. {
  555.   if ((s_init&MUSIC_INITIALIZED) && data)
  556.   {
  557.     if (sosMIDISongDone((W32)song_id)==_FALSE)
  558.       return 1;
  559.     else return 0;
  560.   } else return 0;
  561. }
  562.  
  563.  
  564. song::~song() 
  565. {
  566.   if (data)
  567.   {
  568.     if (s_init&MUSIC_INITIALIZED)
  569.       sosMIDIUnInitSong((W32)song_id);
  570.     jfree(data);
  571.   }
  572. }
  573.  
  574.  
  575.  
  576.  
  577.  
  578.  
  579.  
  580.